#ifndef __Physics_Server_H
#define __Physics_Server_H

#include <vector>

/**
Predeclaration to save compile time
*/
namespace Physics {
	class CEntity;
}

/**
Physics namespace gathers everything with physics for the architecture.

@author Carlos Fraguas
@date December, 2013
*/
namespace Physics {
	/**
	Main class for physics engine. It manages entities which deal with
	physics and simulates their behaviour, including collision detection
	<p>
	It's a Singleton with explicit initialization (meaning construction
	is done via Init() and destruction is done via Release() methods).

	@author Carlos Fraguas
	@date December, 2013
	*/
	class CServer {
	private:
		/**
		Helper method to deliver messages when two entities collide
		*/
		void checkCollisions() const;

		/**
		Helper method to check for entities entering triggers
		*/
		void checkTriggersEnter() const;

	protected:
		/**
		CServer unique instance
		*/
		static CServer *_instance;

		/**
		Alias for scene type, for easier referencing when creating iterators
		*/
		typedef std::vector<CEntity *> TScene;

		/**
		List of physics entities which are part of the physics scene
		*/
		TScene _scene;

		/**
		List of triggers in the scene
		*/
		TScene _triggers;

		/**
		Class constructor
		*/
		CServer();

		/**
		Class destructor
		*/
		virtual ~CServer();

	public:
		/**
		Gets CServer unique instance

		@return CServer*
		*/
		static Physics::CServer *getSingletonPtr() {
			return _instance;
		}

		/**
		Initializes physics server and creates default values for its
		properties.

		@return boolean initialization was correct or not
		*/
		static bool Init();

		/**
		Releases physics engine, destroying anything which could be left over.
		Must be called when application is closing
		*/
		static void Release();

		/**
		Method invoked once per frame, to deal with physics

		@param msecs Milliseconds since last frame
		*/
		void tick(float secs);

		/**
		To deal with physics, every physics object should be part of
		a physics scene. We would create scenes for each map (even several
		scenes per map, or even physics volumes) and have a list of active
		scenes.
		However, we're taking it the easy way and assume we just have
		an active physics scene which is in fact managed by this server.
		This way, when we call this method, previous info is discarded.
		*/
		bool initPhysicsScene();

		/**
		We're assuming just one physics scene exists at a given time,
		so this server is managing it.
		This method will remove every physics entity in the scene, but won't
		destroy any of them as that's part of the physics component
		*/
		bool releasePhysicsScene();

		/**
		Adds a physics entity to the scene

		@param CEntity* entity to be added
		@param bool entity is a trigger or a complete physics entity
		*/
		void addEntity(CEntity *entity, bool isTrigger = false);

		/**
		Removes a physics entity from the scene

		@param CEntity* entity to be removed
		*/
		void removeEntity(CEntity *entity);
	};
}

#endif